package com.itheima.gatewayapp.filter;

import com.itheima.common.constants.SystemConstants;
import com.itheima.common.util.AppJwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.regex.Pattern;

/**
 * @version 1.0
 * @description 说明
 * @package com.itheima.gatewayadmin.filter
 */
@Component
@Slf4j
public class AuthorizeFilter implements GlobalFilter, Ordered {

    // 登录路径的正则表达式
    private Pattern pattern = Pattern.compile("/login/*");

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取请求与响应对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        // 获取请求路径
        String path = request.getURI().getPath();
        log.debug("请求了路径:{}", path);
        //2.1 判断请求路径是否为白名单(登录请求)
        if(pattern.matcher(path).find()) {
            //2.2 如果是登录请求则放行
            //【不要漏了return】
            return chain.filter(exchange);
        }
        //2.3 不是登录请求
        //3. 获取请求头中的token
        String token = request.getHeaders().getFirst("token");
        //4. 有值，
        ////【不要漏了感叹号】
        if(!StringUtils.isEmpty(token)){
            //校验token的有效性,
            try {
                // 解析token得到载荷
                Claims claims = AppJwtUtil.getClaimsBody(token);
                // 获取载荷中的id, long
                Long loginUserId = claims.get("id",Long.class);
                String headImage = claims.get(SystemConstants.LOGIN_USER_IMAGE,String.class);
                String nickname = claims.get(SystemConstants.LOGIN_USER_NAME,String.class);
                // 存入请求头
                request.mutate().header(SystemConstants.USER_HEADER_NAME, loginUserId.toString());
                request.mutate().header(SystemConstants.LOGIN_USER_IMAGE, headImage);
                request.mutate().header(SystemConstants.LOGIN_USER_NAME, nickname);
                // 解析成功不出错则代表token是有效的
                return chain.filter(exchange);
            } catch (ExpiredJwtException ex) {
                // token的有效期已经到了，token要失效了
            } catch (Exception e) {
                // token被修改了，或不是我们系统生成的
            }
        }
        //5. 无效或无token则返回401，阻止，让前端重新登录
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        return response.setComplete();
    }

    @Override
    public int getOrder() {
        return 0;
    }

    public void count(){
        String[] sA={"0","1"};
        String[] sA2={"0","1"};
        int rtn=0;

        // 条件sA=0的个数时x，计算sA2的长度l， rtn = x*l
        // sA=1 y, sA2中1个数为z rtn+=y*z


        for(int i=0;i<sA.length;i++){
            if("0".equals(sA[i])){
                rtn+=sA2.length;
                continue;
            }
            if("1".equals(sA[i])){
                for(int j=0;j<sA2.length;j++){
                    if("1".equals(sA2[j])){
                        rtn++;
                    }
                }
            }
        }
    }



    public void count2(){
        String[] sA={"0","1"};
        String[] sA2={"0","1"};
        int rtn=0;
        for(int i=0;i<sA.length;i++){
            for(int j=0;j<sA2.length;j++){
                boolean lxbz = false;
                if("0".equals(sA[i]) && "0".equals(sA2[j])){
                    lxbz=true;
                }
                if(!lxbz){
                    if("1".equals(sA[i]) && "1".equals(sA2[j])){
                        lxbz=true;
                    }
                }
                if(!lxbz){
                    if("0".equals(sA[i]) ){
                        lxbz=true;
                    }else{
                        continue;
                    }
                }
                if(lxbz){
                    rtn++;
                }
            }
        }
    }
}
